#include "Epoll.h"

Epoll::Epoll()
{
    epollfd_ = epoll_create(size);
    if (epollfd_ == -1)
    {
        printf("epoll_create() failed(%d):%s\n", errno, strerror(errno));
        exit(-1);
    }
}
Epoll::~Epoll()
{
    close(epollfd_);
}
void Epoll::addfd(int fd, uint32_t event)
{
    epoll_event ev;
    ev.data.fd = fd;
    ev.events = event;
    int result = epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev);
    if (result == -1)
    {
        printf("addfd() failed(%d):%s\n", errno, strerror(errno));
        exit(-1);
    }
}


void Epoll::updatechannel(Channel *ch)
{
    epoll_event ev;           // 声明事件的数据结构。
    ev.data.ptr = ch;         // 指定channel。
    ev.events = ch->getEvent();  // 指定事件。

    if (ch->inpoll()) // 如果channel已经在树上了。
    {
        if (epoll_ctl(epollfd_, EPOLL_CTL_MOD, ch->getFd(), &ev) == -1)
        {
            perror("epoll_ctl() failed.\n");
            exit(-1);
        }
    }
    else // 如果channel不在树上。
    {
        if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, ch->getFd(), &ev) == -1)
        {
            perror("epoll_ctl() failed.\n");
            exit(-1);
        }
        ch->setInEpoll(); // 把channel的inepoll_成员设置为true。
    }
}

std::vector<Channel*> Epoll::loop(int timeout)
{
    std::vector<Channel*> channels;
    bzero(events_, sizeof(events_));
    int infds = epoll_wait(epollfd_, events_, MaxEventNums, timeout);
    // 返回失败。
    if (infds < 0)
    {
        perror("epoll_wait() failed");
        exit(-1);
    }

    // 超时。
    if (infds == 0)
    {
        printf("epoll_wait() timeout.\n");
        return channels;
    }

    // 这里分开写你有可能立即而不到位了 ，就是我们epoll返回的就绪事件是返回的event ，fd是这个event的属性之一，我们addevent也是把event加上去啊，他是把这个event加到红黑树上
    for (int i = 0; i < infds; i++)
    {
        Channel *ch=(Channel *)events_[i].data.ptr; 
        ch->setRevents(events_[i].events); 
        channels.push_back(ch);
    }
    return channels;
}
